Many modern computer systems are designed to provide a wide variety of functionalities to a distributed collection of users. In many cases, computer systems are designed to support a flexible set of services that can be expanded by installing additional software applications. Because many computing systems are tasked with providing a wide variety of complex services to users, installation and configuration of the necessary applications can be a time-consuming process. Additionally, manual installation and configuration of the applications can often lead to user-induced errors. Moreover, for distributed systems in which functionality is provided jointly by clients and servers, coordinating the installation and configuration of software applications can be even more difficult and time-consuming.